package cn.darkhorse.workflow.service.impl;

import cn.darkhorse.api.BusinessTaskDTO;
import cn.darkhorse.api.IActivitiService;
import cn.darkhorse.core.consts.WorkflowParamConsts;
import cn.darkhorse.core.param.WorkflowParamAnalysis;
import cn.darkhorse.entity.BpmnWorkflowParam;
import cn.darkhorse.exception.InteractionFailedException;
import cn.darkhorse.workflow.auto.entity.*;
import cn.darkhorse.workflow.auto.service.*;
import cn.darkhorse.workflow.dao.ApprovalOpinionDao;
import cn.darkhorse.workflow.dao.BpmnNotifierDao;
import cn.darkhorse.workflow.dao.BpmnUserAndPostDao;
import cn.darkhorse.workflow.service.ISysUserAndPostExtService;
import cn.darkhorse.workflow.service.IWorkflowToolService;
import cn.darkhorse.workflow.tool.WorkflowConstants;
import cn.darkhorse.workflow.vo.ActivityTaskVo;
import cn.darkhorse.workflow.vo.TaskAndUsersVO;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.identity.User;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.IdentityLinkType;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: mr.wang
 * @time: 2020/7/3 0003 16:03
 */
@Service
public class WorkflowToolServiceImpl implements IWorkflowToolService{
	
	@Autowired
	IBpmnWorkflowService iBpmnWorkflowService;
	@Autowired
	IActivitiService iActivitiService;
	@Autowired
	IBpmnTaskService iBpmnTaskService;
	@Autowired
	IBpmnFlowService iBpmnFlowService;
	@Autowired
	IBpmnWorkflowParamService iBpmnWorkflowParamService;
	@Autowired
	IBusinessWorkflowService iBusinessWorkflowService;
    @Autowired
	WorkflowParamAnalysis workflowParamAnalysis;
    @Autowired
	IProjectApprovalOpinionsService iProjectApprovalOpinionsService;
	@Resource
	BpmnNotifierDao notifierDao;
	@Resource
	BpmnUserAndPostDao bpmnUserAndPostDao;
	@Resource
	ISysUserAndPostExtService sysUserAndPostExtService;
	@Resource
	IBpmnTransferHistoryService iBpmnTransferHistoryService;
	
	
	@Resource
	private HistoryService historyService;
	@Resource
	private TaskService taskService;
	@Resource
	private IdentityService identityService;
	@Resource
	private IBpmnSysUserService iBpmnSysUserService;

	/**
	 * 查询可选流程
	 * @param type
	 * @return
	 */
	@Override
	public List<Map<String,Object>> getWorkflow(String type,String userName){
		if(StringUtils.isBlank(userName)){
			return null;
		}
		List<String> posts = bpmnUserAndPostDao.getPostsByUserId(userName);
		if(null == posts || posts.size() == 0){
			return null;
		}
		
		QueryWrapper<BpmnWorkflow> wrapper = new QueryWrapper<>();
		wrapper.eq("type_id",type);
		wrapper.select("process_name","id","start_candidate_post","process_key");
		wrapper.eq("is_delete", WorkflowConstants.DELETE_FALSE);
		wrapper.eq("is_public", WorkflowConstants.IS_PUBLIC_PUBLIC);
		wrapper.eq("is_apply", WorkflowConstants.IS_APPLY_YES);
		wrapper.ne("start_candidate_post", "");
		List<Map<String,Object>> workflows = iBpmnWorkflowService.listMaps(wrapper);
		if(workflows!=null&&workflows.size()>0){
			Iterator<Map<String, Object>> iterator = workflows.iterator();
			while (iterator.hasNext()){
				Map<String, Object> map = iterator.next();
				//去掉字符数据外壳包裹
				String candidatePost = (String)map.get("start_candidate_post");
				List<String> postCodes = removePackage(candidatePost);
				if(Collections.disjoint(posts,postCodes)){
					iterator.remove();
				}
			}
			return WorkflowConstants.underlineToHump(workflows);
		}
		return null;
	}
	
	
	
	
	
	
	/**
	 * 开启审批
	 * @param businessId
	 * @param workflowId
	 * @return
	 */
	@Override
	public <T> String startProcessInstance(String businessId, String workflowId, Class<T> tClazz, T form, String type,String userName){
		BpmnWorkflow workflow = iBpmnWorkflowService.getById(workflowId);
		//创建工作流实例接口
		Map<String,Object> map = getMap(workflow.getProcessKey(),businessId,tClazz,form,userName);
		String bl = iActivitiService.startProcessInstanceByKey(workflow.getProcessKey(),businessId,map);
		//校验用户停用
		//List<String> names = checkNextUserStatus(bl);
		//转办人
		//transferTasks(names,bl);
		//是否已发起
		isStrat(Long.valueOf(businessId.substring(businessId.indexOf(":")+1,businessId.length())),bl,type,workflowId);
		
		BusinessWorkflow businessWorkflow = new BusinessWorkflow();
		businessWorkflow.setBusinessId(Long.valueOf(businessId.substring(businessId.indexOf(":")+1,businessId.length())));
		businessWorkflow.setWorkflowExampleId(bl);
		businessWorkflow.setType(type);
		businessWorkflow.setWorkflowId(Long.valueOf(workflowId));
		businessWorkflow.setApplierName(userName);
		iBusinessWorkflowService.save(businessWorkflow);
		return bl;
	}
	
	private void isStrat(Long businessId,String bl,String type,String workflowId){
		LambdaQueryWrapper<BusinessWorkflow> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.eq(BusinessWorkflow::getBusinessId,businessId)
					.eq(BusinessWorkflow::getWorkflowExampleId,bl)
					.eq(BusinessWorkflow::getType,type)
					.eq(BusinessWorkflow::getWorkflowId,workflowId)
					.eq(BusinessWorkflow::getState,0);
		long count = iBusinessWorkflowService.count(queryWrapper);
		if(count > 0){
			throw new InteractionFailedException("单据已发起审批!");
		}
	}
	
	
	
	
	
	
	
	private List<TaskAndUsersVO> tus;
	private boolean isClaim;
	
	/**
	 * 校验下一节点审批人状态
	 */
	private List<String> checkNextUserStatus2(String workFlowId){
		tus = new ArrayList<>();
		List<String> userNames = new ArrayList<>();
		JSONArray currentNodeInformation = getCurrentNodeInformation2(workFlowId);
		if(null != currentNodeInformation &&currentNodeInformation.size()>0){
			  isClaim = currentNodeInformation.getJSONObject(0).getBoolean("isClaim");
				for(int i = 0;i<currentNodeInformation.size();i++){
					JSONObject node = currentNodeInformation.getJSONObject(i);
					String userName = node.getString("responsible_person");
					String taskKey = node.getString("taskKey");
					String taskId = node.getString("taskId");
					//设置任务节点和用户
					setTaskUsers(taskId,userName,taskKey);
					userNames.add(userName);
				}
				
			/*List<BpmnSysUser> stopUser = sysUserAndPostExtService.stopTransferUser(userNames,0);
			if((stopUser.size() == userNames.size()) || !isClaim &&stopUser.size()>0){
				StringBuilder sb = new StringBuilder();
				for(BpmnSysUser user:stopUser){
					sb.append(user.getNickName());sb.append("、");
				}
				sb.delete(sb.toString().lastIndexOf("、"), sb.toString().length());
				throw new InteractionFailedException(String.format("下一审批节点审批人【%s】已停用，请通知管理员!",sb.toString()));
			}*/
		}
		return userNames;
	}
	
	private void setTaskUsers(String taskId,String userName,String taskKey){
		TaskAndUsersVO tu = new TaskAndUsersVO();
		tu.setUserName(userName);
		tu.setTaskId(taskId);
		tu.setTaskKey(taskKey);
		tus.add(tu);
	}
	
	/**
	 * 转办
	 */
	private List<TaskAndUsersVO> transferTasks(List<String> userNames){
	
		if(null != tus && tus.size()>0){
			List<BpmnSysUser> transferUser = sysUserAndPostExtService.stopTransferUser(userNames);
			if(transferUser != null && transferUser.size() > 0){
				//停用设置交接人
				List<BpmnSysUser> handoverStopUsers = new ArrayList<>();
				//停用未设置交接人
				List<BpmnSysUser> noHandoverStopUsers = new ArrayList<>();
				List<TaskAndUsersVO> autoAgree = new ArrayList<>();
				for(BpmnSysUser user:transferUser){
					String handoverPerson = user.getHandoverPerson();
					if(StringUtils.isNotBlank(handoverPerson)){
						handoverStopUsers.add(user);
					}else {
						noHandoverStopUsers.add(user);
					}
				}
				if(isClaim){
					//是否相对岗位
					boolean relativePost = isRelativePost(tus.get(0).getTaskKey());
					String taskId = tus.get(0).getTaskId();
					//没有设置交接人
					if(tus.size() == transferUser.size() && (handoverStopUsers == null || handoverStopUsers.size() == 0)){
						TaskAndUsersVO tu = new TaskAndUsersVO();
						tu.setTaskId(taskId);tu.setTaskKey(tus.get(0).getTaskKey());
						tu.setUserName(noHandoverStopUsers.get(0).getUserName());
						if(null!=noHandoverStopUsers&&noHandoverStopUsers.size()>0){
							StringBuffer sb=new StringBuffer();
							noHandoverStopUsers.forEach(item->{
								if(sb.length()==0){
									sb.append(item.getNickName())
											.append("(已停用)");
								}else{
									sb.append(",")
											.append(item.getNickName())
											.append("(已停用)");
								}
							});
							tu.setReRamrks(sb.toString());
						}
						autoAgree.add(tu);
						//todo 随便返回一个用户
						return autoAgree;
					}

					//停用并设置交接人
					for(BpmnSysUser user:handoverStopUsers){
						String handoverPerson = user.getHandoverPerson();
						if(relativePost){
							taskService.deleteUserIdentityLink(taskId,user.getUserName(),IdentityLinkType.ASSIGNEE);
							taskService.addCandidateUser(taskId, handoverPerson);
							return null;
						}
						taskService.deleteCandidateUser(taskId, user.getUserName());
						taskService.addCandidateUser(taskId, handoverPerson);
					}
				}else{
					for(TaskAndUsersVO t:tus){
						String assignee = t.getUserName();
						String taskId = t.getTaskId();
						//并发未设置交接人
						if(null != noHandoverStopUsers &&noHandoverStopUsers.size() >0){
							for(BpmnSysUser user:noHandoverStopUsers){
								if(assignee.equals(user.getUserName())){
									TaskAndUsersVO tu = new TaskAndUsersVO();
									tu.setTaskId(taskId);tu.setTaskKey(t.getTaskKey());
									tu.setUserName(user.getUserName());
									tu.setReRamrks(user.getNickName()+"(已停用)");
									autoAgree.add(tu);
								}}
						}
						//停用设置交接人
						if(null != handoverStopUsers && handoverStopUsers.size()>0){
							for(BpmnSysUser user:handoverStopUsers){
								if(assignee.equals(user.getUserName())){
									String handoverPerson = user.getHandoverPerson();
									iActivitiService.transferTask(taskId, handoverPerson);
								}
							}
						}
					}
					//todo 返回未设置用户
					return autoAgree;
				}

			//正常用户
			}else{
				//抢占
				if(isClaim){
					if(null!=tus&&tus.size()==1&&"空".equals(tus.get(0).getUserName())){
						List<TaskAndUsersVO> autoAgree=new ArrayList<>();
						TaskAndUsersVO vo=tus.get(0);
						vo.setReRamrks("空");
						autoAgree.add(vo);
						return autoAgree;
					}
				}else{
					if(null!=tus&&tus.size()==1&&"空".equals(tus.get(0).getUserName())){
						List<TaskAndUsersVO> autoAgree=new ArrayList<>();
						TaskAndUsersVO vo=tus.get(0);
						vo.setReRamrks("空");
						autoAgree.add(vo);
						return autoAgree;
					}
				}
			}

		}
		return null;
	}
	
	/**
	 * 校验下一节点审批人状态
	 */
	private List<String> checkNextUserStatus(String workFlowId){
		tus = new ArrayList<>();
		List<String> userNames = new ArrayList<>();
		JSONArray currentNodeInformation = getCurrentNodeInformation2(workFlowId);
		if(null != currentNodeInformation &&currentNodeInformation.size()>0){
			isClaim = currentNodeInformation.getJSONObject(0).getBoolean("isClaim");
			for(int i = 0;i<currentNodeInformation.size();i++){
				JSONObject node = currentNodeInformation.getJSONObject(i);
				String userName = node.getString("responsible_person");
				String taskKey = node.getString("taskKey");
				String taskId = node.getString("taskId");
				//设置任务节点和用户
				setTaskUsers(taskId,userName,taskKey);
				userNames.add(userName);
			}
			List<BpmnSysUser> stopUser = sysUserAndPostExtService.stopTransferUser(userNames,0);
			if((stopUser.size() == userNames.size()) || !isClaim &&stopUser.size()>0){
				StringBuilder sb = new StringBuilder();
				for(BpmnSysUser user:stopUser){
					sb.append(user.getNickName());sb.append("、");
				}
				sb.delete(sb.toString().lastIndexOf("、"), sb.toString().length());
				throw new InteractionFailedException(String.format("下一审批节点审批人【%s】已停用，请通知管理员!",sb.toString()));
			}
		}
		return userNames;
	}
	/**
	 * 转办
	 */
	private void transferTasks(List<String> userNames,String id){
		
		if(null != tus && tus.size()>0){
			List<BpmnSysUser> transferUser = sysUserAndPostExtService.stopTransferUser(userNames,1);
			if(transferUser != null && transferUser.size() > 0){
				if(isClaim){
					//是否相对岗位
					boolean relativePost = isRelativePost(tus.get(0).getTaskKey());
					String taskId = tus.get(0).getTaskId();
					for(BpmnSysUser user:transferUser){
						String handoverPerson = user.getHandoverPerson();
						if(relativePost){
							taskService.deleteUserIdentityLink(taskId,user.getUserName(),IdentityLinkType.ASSIGNEE);
							taskService.addCandidateUser(taskId, handoverPerson);
							return ;
						}
						taskService.deleteCandidateUser(taskId, user.getUserName());
						taskService.addCandidateUser(taskId, handoverPerson);
						//iActivitiService.transferTask(taskId, handoverPerson);
					}
				}else{
					for(TaskAndUsersVO t:tus){
						String assignee = t.getUserName();
						String taskId = t.getTaskId();
						for(BpmnSysUser user:transferUser){
							if(assignee.equals(user.getUserName())){
								String handoverPerson = user.getHandoverPerson();
								iActivitiService.transferTask(taskId, handoverPerson);
                /*if(users.add(user.getHandoverPerson())){
                  iActivitiService.transferTask(taskId, handoverPerson);
                }else{
                  taskService.deleteUserIdentityLink(taskId,user.getUserName(), IdentityLinkType.PARTICIPANT);
                  taskService.deleteUserIdentityLink(taskId,user.getUserName(), IdentityLinkType.ASSIGNEE);
                }*/
							}
						}
					}
				}
				
			}
		}
		
	}
	
	
	
	/**
	 * 获取流实例参数，以便后期创建流程实例
	 * @param workflowKey
	 * @param businessId
	 * @return
	 */
	public <T> Map<String,Object> getMap(String workflowKey,String businessId, Class<T> tClazz,T form,String userName){
		QueryWrapper<BpmnWorkflowParam> wrapper = new QueryWrapper<>();
		wrapper.eq("process_key",workflowKey);
		List<BpmnWorkflowParam> workflowParams = iBpmnWorkflowParamService.list(wrapper);
		Map<String,Object> map = workflowParamAnalysis.doAnalysis(workflowParams,tClazz,form,userName);
		return map;
	}
	
	/**
	 * 是否相对岗位
	 * @param taskKey
	 * @return
	 */
	private boolean isRelativePost(String taskKey){
		boolean relativePost = false;
		LambdaQueryWrapper<BpmnWorkflowParam> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(BpmnWorkflowParam::getElementKey,taskKey);
		BpmnWorkflowParam param = iBpmnWorkflowParamService.getOne(wrapper);
		if(null != param){
			String paramClass = param.getParamClass();
			if(WorkflowParamConsts.CLASS_TASK_RELATIVE_POST.equals(paramClass)){
				relativePost = true;
			}
		}
		return relativePost;
	}
	
	/**
	 * 登录用户查询待办事项
	 * @param userName
	 * @return
	 */
	@Override
	public List<Map<String,Object>> getSchedule(String userName){
		List<Map<String,Object>> list = new ArrayList<>();
			StringBuffer stringBuffer = new StringBuffer();
			List<BusinessTaskDTO> bt = iActivitiService.queryBusinessTasksByUserName(userName);
			if(bt!=null&&bt.size()>0){
				for(BusinessTaskDTO b:bt){
					Map<String,Object> params = new HashMap<>(16);
					params.put("taskKey",b.getTaskKey());
					params.put("businessId",b.getBussinessId());
					params.put("businessType",b.getByssinessType());
					params.put("taskId",b.getTaskId());
					params.put("processInstanceId",b.getProcessInstanceId());
					BpmnTask task = iBpmnTaskService.getOne(new QueryWrapper<BpmnTask>().eq("task_key",b.getTaskKey()));
					params.put("taskName",task.getTaskName());
					list.add(params);
				}
			}
		return list;
	}
	
	@Resource
	private ApprovalOpinionDao approvalOpinionDao;
	
	/**
	 * 查看审批表单意见
	 * @param businessId
	 * @returnnfof
	 */
	@Override
	public List<ProjectApprovalOpinions> getApprovalFormInfo(String businessId,String businessType){
		/*QueryWrapper<ProjectApprovalOpinions> wrapper = new QueryWrapper<>();
		wrapper.eq("business_id",businessId)
				.eq("business_type",businessType);
		List<ProjectApprovalOpinions>  approvalOpinions = iProjectApprovalOpinionsService.list(wrapper);*/
		List<ProjectApprovalOpinions> approvalOpinions = approvalOpinionDao.getOpinionsList(businessId, businessType);
		if(null!=approvalOpinions&&approvalOpinions.size()>0){
			approvalOpinions.forEach(item->{
				if(StringUtils.isNotBlank(item.getExRemarks())){
					item.setApprovedBy(item.getExRemarks());
				}
			});
		}
		return approvalOpinions;
	}

	@Override
	public List<ProjectApprovalOpinions> getApprovalFormInfo2(String businessId, String businessType) {
		QueryWrapper<ProjectApprovalOpinions> wrapper = new QueryWrapper<>();
		wrapper.eq("business_id",businessId)
				.eq("business_type",businessType)
				.eq("is_apply",1);
		List<ProjectApprovalOpinions>  approvalOpinions = iProjectApprovalOpinionsService.list(wrapper);
		return approvalOpinions;
	}


	/**
	 * 获取审批权限（同意，不同意，否决）
	 * @param taskKey
	 * @return
	 */
	@Override
	public Map<String,Object> getApprovalAuthority(String taskKey,String taskId,String workflowExampleId){
		boolean b = approvalIsOutOfDate(workflowExampleId, taskId);
		Map<String,Object> map = getTaskData(taskKey);
		if(b){
			map.put("approvalOption", "[]");
		}
		return map;
	}
	
	/**
	 *根据taskKey获取task基本信息
	 * @param taskKey
	 * @return
	 */
	public Map<String,Object> getTaskData(String taskKey){
		QueryWrapper<BpmnTask> wrapper = new QueryWrapper<>();
		wrapper.eq("task_key",taskKey);
		wrapper.select("approval_option","is_claim","id");
		Map<String,Object> map = iBpmnTaskService.getMap(wrapper);
		map = WorkflowConstants.underlineToHumpSub(map);
		return map;
	}
	
	/**
	 * 确认审批
	 * @param confirmApproval
	 * @return
	 */
	@Transactional(rollbackFor = RuntimeException.class)
	@Override
	public Map<String,Object> confirmApproval(ConfirmApproval confirmApproval,String typeB){
		Map<String,Object> result = new HashMap<>();
		result.put("result",true);
		result.put("resultValue",-1);
		result.put("resultType",0);
		result.put("businessId",0);
		String businessId = confirmApproval.getBusinessId();
		String taskId = confirmApproval.getTaskId();
		Integer type = confirmApproval.getType();
		String taskKey = confirmApproval.getTaskKey();
		String businessType = confirmApproval.getBusinessType();
		String userName = confirmApproval.getUserName();
		if(StringUtils.isEmpty(businessId)||StringUtils.isEmpty(taskId)||type==null||StringUtils.isEmpty(taskKey)||StringUtils.isEmpty(userName)){
			 result.put("result",false);
			 return  result;
		}
		result.put("businessId",businessId);
		String workflowExampleId = null;
		QueryWrapper<BusinessWorkflow> wrapper = new QueryWrapper();
		wrapper.eq("business_id",businessId);
		wrapper.eq("state", WorkflowConstants.NORMAL);
		wrapper.eq("type",typeB);
		BusinessWorkflow businessWorkflow = iBusinessWorkflowService.getOne(wrapper);
		Map<String,Object> map = getTaskData(taskKey);
		String isClaim = String.valueOf(map.get("isClaim"));
		if(WorkflowConstants.SEIZE.equals(isClaim)){
			iActivitiService.claim(taskId,userName);
		}
		
		// 保存审核结论和
		addApprovalOpinions(confirmApproval);
		
		if(WorkflowConstants.AGREE == type){
			workflowExampleId = agree(taskId,businessWorkflow,result,confirmApproval,userName);
			//用户停用校验
			//List<String> names = checkNextUserStatus(businessWorkflow.getWorkflowExampleId());
			//转办人
			//transferTasks(names, businessWorkflow.getWorkflowExampleId());
		}else if(WorkflowConstants.DISAGREE == type){
			disagree(taskId,businessWorkflow,result);
			//修改审批意见应用状态
			updateApprovalOpinions(businessId,businessType);
		}else if(WorkflowConstants.VETO == type){
			veto(taskId,businessWorkflow,result);
			//修改审批意见应用状态
			//updateApprovalOpinions(businessId,businessType);
		}else{
			result.put("result",false);
			return result;
		}
		
		iBusinessWorkflowService.saveOrUpdate(businessWorkflow);
		//throw new InteractionFailedException("流程实例不存在");
		return result;
	}
	
	/**
	 * 停用自动执行的用户
	 * @param workflowExampleId
	 * @return
	 */
	@Override
	public List<TaskAndUsersVO> stopUserNoHandover(String workflowExampleId){
		//用户停用校验
		List<String> names = checkNextUserStatus2(workflowExampleId);
		//转办人
		List<TaskAndUsersVO> taskUsers = transferTasks(names);
		return taskUsers;
	}
	

	
	
	
	
	/**
	 * 同意
	 */
	private String agree(String taskId,BusinessWorkflow businessWorkflow,Map<String,Object> result,ConfirmApproval confirmApproval,String userName){
		String workflowExampleId = "";
		if(businessWorkflow!=null){
			workflowExampleId = businessWorkflow.getWorkflowExampleId();
		}
		List<BusinessTaskDTO>  businessTaskDTOS= null;
		iActivitiService.agree(taskId);
		while (true){
			businessTaskDTOS = iActivitiService.queryBusinessTasksByUserNameAndProcessId(confirmApproval.getUserName(),confirmApproval.getProcessInstanceId());
			if(businessTaskDTOS!=null&&businessTaskDTOS.size()>0){
				Map<String,Object> map = getTaskData(businessTaskDTOS.get(0).getTaskKey());
				String isClaim = String.valueOf(map.get("isClaim"));
				if(WorkflowConstants.SEIZE.equals(isClaim)){
					iActivitiService.claim(businessTaskDTOS.get(0).getTaskId(),userName);
				}
				iActivitiService.agree(businessTaskDTOS.get(0).getTaskId());
			}else{
				break;
			}
		}
		if(iActivitiService.processIsOverById(workflowExampleId)){
			result.put("resultValue", WorkflowConstants.REVIEWED);
			result.put("resultType", WorkflowConstants.AGREE);
			businessWorkflow.setState(WorkflowConstants.VETO);
		}else{
			result.put("resultType", WorkflowConstants.PROCESS_AGREE);
			result.put("resultValue", WorkflowConstants.REVIEWED);
		}
		
		return workflowExampleId;
	}
	
	/**
	 * 不同意
	 */
	private void disagree(String taskId,BusinessWorkflow businessWorkflow,Map<String,Object> result){
		iActivitiService.disagree(taskId);
		businessWorkflow.setState(WorkflowConstants.CONTRACT_EXAMPLE);
		result.put("resultValue", WorkflowConstants.PENDING_TRIAL);
		result.put("resultType", WorkflowConstants.DISAGREE);
	}
	/**
	 * 否决
	 */
	private void veto(String taskId,BusinessWorkflow businessWorkflow,Map<String,Object> result){
		iActivitiService.reject(taskId);
		businessWorkflow.setState(WorkflowConstants.CONTRACT_EXAMPLE);
		result.put("resultValue", WorkflowConstants.TO_VOID);
		result.put("resultType", WorkflowConstants.VETO);
	}
	
	
	/**
	 * 保存节点审批意见
	 * @param confirmApproval
	 */
	private void addApprovalOpinions(ConfirmApproval confirmApproval){
		String businessType = confirmApproval.getBusinessType();
		String approvalOpinions = confirmApproval.getApprovalOpinions();
		String attachments = confirmApproval.getAttachments();
		// 保存审核结论和
		ProjectApprovalOpinions approval = new ProjectApprovalOpinions();
		approval.setWorkflowExampleId(confirmApproval.getProcessInstanceId());
		approval.setBusinessId(Long.valueOf(confirmApproval.getBusinessId()));
		approval.setConclusion(confirmApproval.getType());
		approval.setApprovedBy(confirmApproval.getUserName());
		approval.setRemarks(approvalOpinions);
		approval.setAttachments(attachments);
		approval.setBusinessType(businessType);
		approval.setExRemarks(confirmApproval.getExRemarks());
		iProjectApprovalOpinionsService.saveOrUpdate(approval);
	}
	
	/**
	 * 将上一次流审批意见修改为非应用（再次发生时）
	 * @param businessId
	 * @param businessType
	 */
	private void updateApprovalOpinions(String businessId,String businessType){
		LambdaUpdateWrapper<ProjectApprovalOpinions> wrapper = new LambdaUpdateWrapper<>();
			wrapper.eq(ProjectApprovalOpinions::getBusinessId,businessId)
					.eq(ProjectApprovalOpinions::getBusinessType,businessType)
					.set(ProjectApprovalOpinions::getIsApply, WorkflowConstants.IS_APPLY_NO);
		iProjectApprovalOpinionsService.update(wrapper);
	}
	
	
	
	
	

	
	/**
	 * 获取流程节点办理人员
	 * @param businessId
	 * @param workflowType
	 * @return
	 */
	@Override
	public JSONObject getNodeHandlers(String businessId, String workflowType,String businessType, String workflowId,String userName,Long projectId) {
		LambdaQueryWrapper<BusinessWorkflow> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(BusinessWorkflow::getBusinessId,businessId)
					.eq(BusinessWorkflow::getType,workflowType)
					.eq(BusinessWorkflow::getState, WorkflowConstants.NORMAL);
		//获取当前流程实例ID
		BusinessWorkflow workflow = iBusinessWorkflowService.getOne(wrapper);
		if(null == workflow){
			throw new InteractionFailedException("流程实例不存在");
		}
		BpmnWorkflow bpmnWorkflow = iBpmnWorkflowService.getById(workflowId);
		String workflowExampleId = workflow.getWorkflowExampleId();
		String applierName =workflow.getApplierName();
		//当前节点办理人集合
		JSONObject nodeHandler = getNodeHandler(workflowExampleId,bpmnWorkflow,userName,businessId,businessType,projectId,applierName);
		return nodeHandler;
	}
	
	/**
	 * 获取当前节点办理人
	 * @param workflowExampleId
	 * @return
	 */
	private JSONObject getNodeHandler(String workflowExampleId,BpmnWorkflow bpmnWorkflow,String userName,String businessId,String businessType,Long projectId,String applierName){
		JSONObject paramObj = new JSONObject();
		paramObj.put("creator",userName);
		JSONObject taskObj = new JSONObject();
		taskObj.put("name",bpmnWorkflow.getProcessName()+"01");
		taskObj.put("title", bpmnWorkflow.getProcessName());
		taskObj.put("create_time", WorkflowConstants.dateTransformationString(new Date()));
		taskObj.put("id", workflowExampleId);
		paramObj.put("taskObj", taskObj);
		paramObj.put("nextFlowInforArray",getCurrentNodeInformation(workflowExampleId,businessId,businessType,projectId));
		return paramObj;
		
	}
	
	private com.alibaba.fastjson.JSONArray getCurrentNodeInformation(String workflowExampleId,String businessId,String businessType,Long projectId){
		JSONArray nextArray = new com.alibaba.fastjson.JSONArray();
		List<Task> list = taskService.createTaskQuery().processInstanceId(workflowExampleId).list();
		if(null != list && list.size()>0){
			String taskDefinitionKey = list.get(0).getTaskDefinitionKey();
			boolean claim = isClaim(taskDefinitionKey);
			if(claim){
				boolean isNoPerson = false;
				List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(list.get(0).getId());
				String groupId = identityLinksForTask.get(0).getGroupId();
				for(IdentityLink identityLink:identityLinksForTask ){
					//按照岗位发起的流程
					if(null!=identityLink.getGroupId()){
						/*List<User> users = identityService.createUserQuery().memberOfGroup(identityLink.getGroupId()).list();
						if(null == users || users.size() == 0){
							throw new InteractionFailedException("流程按照岗位形式发起，岗位下无用户审批");
						}
						for(User user:users){
							setValue(nextArray,user.getId(),identityLink.getTaskId(),businessId,businessType,taskDefinitionKey,workflowExampleId,"000",projectId);
						}*/
						List<User> users = identityService.createUserQuery().memberOfGroup(identityLink.getGroupId()).list();
						if(null != users && users.size() > 0){
							for(User user:users){
								isNoPerson = true;
								setValue(nextArray,user.getId(),identityLink.getTaskId(),businessId,businessType,taskDefinitionKey,workflowExampleId,"000",projectId);
							}
						}
					}else{
						setValue(nextArray,identityLink.getUserId(),identityLink.getTaskId(),businessId,businessType,taskDefinitionKey,workflowExampleId,"000",projectId);
					}
				}
				//岗位下无人
				if(StringUtils.isNotBlank(groupId) && !isNoPerson){
					//throw new InteractionFailedException("流程按照岗位形式发起，岗位下无用户审批");
					setValue(nextArray,"空",identityLinksForTask.get(0).getTaskId(),businessId,businessType,taskDefinitionKey,workflowExampleId,"000",projectId);
				}
			}else{
				for(Task t:list){
					List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(t.getId());
					for(IdentityLink identityLink:identityLinksForTask ){
						setValue(nextArray,identityLink.getUserId(),identityLink.getTaskId(),businessId,businessType,taskDefinitionKey,workflowExampleId,t.getTaskDefinitionKey(),projectId);
					}
				}
			}
		}
		return nextArray;
	}
	
	private boolean isClaim(String taskKey){
		boolean result = false;
		LambdaQueryWrapper<BpmnTask> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(BpmnTask::getTaskKey,taskKey);
		BpmnTask task = iBpmnTaskService.getOne(wrapper);
		if(task == null){
			throw new InteractionFailedException("流程任务不存在");
		}
		if(1 == task.getIsClaim()){
			result = true;
		}
		return  result;
	}
	
	private void  setValue(com.alibaba.fastjson.JSONArray nextArray, String userId, String taskId,String businessId,String businessType, String taskDefinitionKey,String workflowExampleId, String taskKey,Long projectId){
		JSONObject nextObj = new JSONObject();
		List<BpmnSysUser> bpmnSysUsers = sysUserAndPostExtService.stopTransferUser(2);
		Map<String,BpmnSysUser>stopMap=bpmnSysUsers.stream().collect(Collectors.toMap(BpmnSysUser::getUserName, Function.identity()));
		if(stopMap.containsKey(userId)){
			BpmnSysUser user=stopMap.get(userId);
			if(StringUtils.isNotBlank(user.getHandoverPerson())){
				userId=user.getHandoverPerson();
			}
		}
		nextObj.put("responsible_person", userId);
		nextObj.put("create_time", WorkflowConstants.dateTransformationString(new Date()));
		nextObj.put("third_app_url", getApprovalParams(businessId,businessType,taskDefinitionKey,taskId,workflowExampleId,projectId));
		nextObj.put("id", taskId+userId);
		nextObj.put("taskKey", taskKey);
		nextArray.add(nextObj);
	}
	
	private String getApprovalParams(String businessId,String businessType,String taskKey,String taskId,String processInstanceId,Long projectId){
		JSONObject params = new JSONObject();
		params.put("businessId",businessId);
		params.put("businessType",businessType);
		params.put("taskKey",taskKey);
		params.put("taskId",taskId);
		params.put("processInstanceId",processInstanceId);
		if(null != projectId){
			params.put("projectId",projectId);
		}
		String s = params.toJSONString();
		String url = String.format("/taskView?businessId=%s&businessType=%s&taskKey=%s&taskId=%s&processInstanceId=%s",
				businessId,businessType,taskKey,taskId,processInstanceId);
		if(null != projectId){
			url = String.format("/taskView?businessId=%s&businessType=%s&taskKey=%s&taskId=%s&processInstanceId=%s&projectId=%s",
					businessId,businessType,taskKey,taskId,processInstanceId,projectId);
		}
		//return "/taskView?"+s;
		return url;

	}

	/**
	 *
	 * @return
	 */
	@Override
	public JSONObject getNodeHandlersAgree(String taskId,String workFlowId,String businessId,String businessType,String taskKey,Long projectId,String applierName) {
		boolean result = true;
		List<Task> list = taskService.createTaskQuery().processInstanceId(workFlowId).list();
		for(Task t:list){
			if(t.getTaskDefinitionKey().equals(taskKey)){
				result = false;
			}
		}
		JSONObject paramObj = new JSONObject();
		HistoricActivityInstance previousNode = getPreviousNode(workFlowId);
		HistoricTaskInstance previoustask = queryUpOneNode(taskId);
		//当前节点信息
		BpmnTask task = getTaskInfo(taskKey);
		JSONObject nextObj = new JSONObject();
		if(StringUtils.isNotBlank(previousNode.getAssignee())) {
			nextObj.put("operator", previousNode.getAssignee());
			//nextObj.put("id", previousNode.getTaskId()+previousNode.getAssignee());
			nextObj.put("id", taskId + previousNode.getAssignee());
		}else{
			nextObj.put("operator", previoustask.getAssignee());
			nextObj.put("id", taskId + previoustask.getAssignee());
		}
		nextObj.put("finished_time", WorkflowConstants.dateTransformationString(previousNode.getEndTime()));
		if(null != task){
			nextObj.put("isClaim", task.getIsClaim());
		}
		paramObj.put("nextFlowInforArray",new com.alibaba.fastjson.JSONArray());
		paramObj.put("currentFlowInfor",nextObj);
		if(result){
			com.alibaba.fastjson.JSONArray currentNodeInformation = getCurrentNodeInformation(workFlowId,businessId,businessType,projectId);
			paramObj.put("nextFlowInforArray",currentNodeInformation);
		}
		paramObj.put("creator",applierName);

		return paramObj;
	}
	
	/**
	 * 获取上一节点信息
	 * @param workflowExampleId
	 * @return 任务节点ID
	 */
	private HistoricActivityInstance getPreviousNode(String workflowExampleId){
		//上一个节点
		// 查找上一个已完成的user task节点
		List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
				.activityType("userTask")
				.processInstanceId(workflowExampleId)
				.finished()
				.orderByHistoricActivityInstanceEndTime()
				.desc()
				.list();
		
		return historicActivityInstances.get(0);
		//return getAssignee(historicActivityInstances);
	}

	/**
	 * 根据任务id获取上一个节点的信息
	 *
	 * @param taskId
	 * @return
	 */
	public  HistoricTaskInstance queryUpOneNode(String taskId) {
		//上一个节点
		List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
				.taskId(taskId).orderByHistoricTaskInstanceEndTime()
				.desc()
				.list();
		HistoricTaskInstance taskInstance = null;
		if (!list.isEmpty()) {
			if (list.get(0).getEndTime() != null) {
				taskInstance = list.get(0);
			}
		}
		return taskInstance;
	}

	
	/**
	 * 获取办理人  当一个人接连同时处理多个任务时，暂定按照上一节点办理人处理
	 * @param historicActivityInstances
	 * @return
	 */
	private HistoricActivityInstance getAssignee(List<HistoricActivityInstance> historicActivityInstances){
		for(HistoricActivityInstance activityInstance:historicActivityInstances){
			String assignee = activityInstance.getAssignee();
			if(StringUtils.isNotBlank(assignee)){
				return activityInstance;
			}
		}
		return null;
	}
	
	
	
	
	
	
	/**
	 * 不同意
	 * @param taskId
	 * @param userName
	 * @param remarks
	 * @return
	 */
	@Override
	public JSONObject getNodeHandlersDisAgree(String taskId, String userName, String remarks,String taskKey) {
		BpmnTask task = getTaskInfo(taskKey);
		JSONObject paramObj = new JSONObject();
		paramObj.put("id", taskId+userName);
		paramObj.put("operator", userName);
		paramObj.put("remark", remarks);
		paramObj.put("taskId", taskId);
		if(null != task){
			paramObj.put("taskName", task.getTaskName());
			paramObj.put("type", WorkflowConstants.DISAGREE);
		}
		
		return paramObj;
	}

	/**
	 * 跳过节点后下一节点获取task信息
	 * @param businessId
	 * @param workflowType
	 * @param workflowId
	 * @return
	 */
	@Override
	public JSONObject getNodeHandlersSkip(String businessId, Long workflowType, String workflowId,String bussinessName) {
		LambdaQueryWrapper<BusinessWorkflow> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(BusinessWorkflow::getBusinessId,businessId)
				.eq(BusinessWorkflow::getType,workflowType)
				.eq(BusinessWorkflow::getState, WorkflowConstants.NORMAL);
		//获取当前流程实例ID
		BusinessWorkflow workflow = iBusinessWorkflowService.getOne(wrapper);
		if(null == workflow){
			wrapper.clear();
			wrapper.eq(BusinessWorkflow::getWorkflowExampleId,workflowId);
			wrapper.isNotNull(BusinessWorkflow::getApplierName);
			List<BusinessWorkflow> workflowList=iBusinessWorkflowService.list(wrapper);
			if(null!=workflowList&&workflowList.size()>0){
				workflow=workflowList.get(0);
			}else{
				throw new InteractionFailedException("流程实例不存在");
			}
		}
		String workflowExampleId = workflow.getWorkflowExampleId();
		JSONObject taskObj = new JSONObject();
		taskObj.put("id", workflowExampleId);
		taskObj.put("applierName", workflow.getApplierName());
		taskObj.put("title",bussinessName);
		return taskObj;
	}


	/**
	 * 获取任务信息
	 * @param taskKey
	 * @return
	 */
	private BpmnTask getTaskInfo(String taskKey){
		LambdaQueryWrapper<BpmnTask> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(BpmnTask::getTaskKey,taskKey);
		BpmnTask task = iBpmnTaskService.getOne(wrapper);
		return task;
	}
	
	
	@Override
	public Map<String,Object> getFlowChart(Long businessId, String businessType,String exampleId) {
		Map<String,Object> result = new HashMap<>();
		BusinessWorkflow businessWorkflow = getBusinessWorkflow(businessId, businessType,exampleId);
		if(null == businessWorkflow){
			return result;
		}
		//流程实例ID
		String workflowExampleId = businessWorkflow.getWorkflowExampleId();
		//流程ID
		Long workflowId = businessWorkflow.getWorkflowId();
		BpmnWorkflow workflow = iBpmnWorkflowService.getById(workflowId);
		if(null == workflow){
			return result;
		}
		result.put("baseXml",workflow.getBaseXml());
		result.put("workflowNode",getWorkflowNodes(workflowExampleId));
		result.put("nextNode",getNextNodes(workflowExampleId));
		result.put("workflowName",workflow.getProcessName());
		return result;
		
	}
	
	
	/**
	 * 获取业务单和流程相关数据
	 * @param businessId
	 * @param businessType
	 * @return
	 */
	private BusinessWorkflow getBusinessWorkflow(Long businessId, String businessType,String exampleId){
		//处理中
		LambdaQueryWrapper<BusinessWorkflow> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(BusinessWorkflow::getType,businessType)
				.eq(BusinessWorkflow::getBusinessId,businessId)
				.eq(BusinessWorkflow::getState, WorkflowConstants.NORMAL);
		BusinessWorkflow businessWorkflow = iBusinessWorkflowService.getOne(wrapper);
		//TODO 20210907 业务单据重复发起,之前通知的消息由于流程结束，获取不到
		/*if(businessWorkflow == null){
			LambdaQueryWrapper<BusinessWorkflow> query = new LambdaQueryWrapper<>();
			query.eq(BusinessWorkflow::getType,businessType)
					.eq(BusinessWorkflow::getBusinessId,businessId)
					.eq(BusinessWorkflow::getState,FieldTranslation.TO_VOID)
					.orderByDesc(BusinessWorkflow::getId);
			List<BusinessWorkflow> bws = iBusinessWorkflowService.list(query);
			if(null != bws && bws.size()>0){
				businessWorkflow = bws.get(0);
			}
		}*/
		//消息查看
		if(StringUtils.isNotBlank(exampleId)){
			LambdaQueryWrapper<BusinessWorkflow> query = new LambdaQueryWrapper<>();
			query.eq(BusinessWorkflow::getType,businessType)
					.eq(BusinessWorkflow::getBusinessId,businessId)
					.eq(BusinessWorkflow::getWorkflowExampleId,exampleId)
					.orderByDesc(BusinessWorkflow::getId);
			List<BusinessWorkflow> bws = iBusinessWorkflowService.list(query);
			if(null != bws && bws.size()>0){
				businessWorkflow = bws.get(0);
			}
		}
		//流程结束
		if(StringUtils.isBlank(exampleId) && null == businessWorkflow){
			LambdaQueryWrapper<BusinessWorkflow> query = new LambdaQueryWrapper<>();
			query.eq(BusinessWorkflow::getType,businessType)
					.eq(BusinessWorkflow::getBusinessId,businessId)
					.eq(BusinessWorkflow::getState, WorkflowConstants.TO_VOID)
					.orderByDesc(BusinessWorkflow::getId);
			List<BusinessWorkflow> bws = iBusinessWorkflowService.list(query);
			if(null != bws && bws.size()>0){
				businessWorkflow = bws.get(0);
			}
		}
		return businessWorkflow;
	}
	
	/**
	 * 获取流程节点办理信息
	 * @param workflowExampleId
	 * @return
	 */
	private Map<String,List<ActivityTaskVo>> getWorkflowNodes(String workflowExampleId){
		Map<String,List<ActivityTaskVo>> result = new HashMap<>();

		List<HistoricActivityInstance> hai = historyService.createHistoricActivityInstanceQuery().processInstanceId(workflowExampleId).finished().list();
		if(null == hai || hai.size() == 0){
			return result;
		}
		//20220907 mao 账号改为昵称
		List<BpmnSysUser> userList=iBpmnSysUserService.list(new LambdaQueryWrapper<BpmnSysUser>()
				.eq(BpmnSysUser::getStatus, WorkflowConstants.NORMAL));
		Map<String,String> userMap=userList.stream().collect(Collectors.toMap(BpmnSysUser::getUserName,BpmnSysUser::getNickName));

		for(HistoricActivityInstance h:hai){
			if("StartEvent_0vzs06g".equals(h.getActivityId())){
				continue;
			}
			List<ActivityTaskVo> voList = result.get(h.getActivityId());
			if(null == result.get(h.getActivityId())){
				/*List<ActivityTaskVo> taskVos = new ArrayList<>();
				ActivityTaskVo atv = new ActivityTaskVo();
				atv.setActivityId(h.getActivityId());
				atv.setActivityName(h.getActivityName());
				atv.setAssignee(h.getAssignee());
				atv.setEndTime(h.getEndTime());
				taskVos.add(atv);*/
				voList = new ArrayList<>();
				result.put(h.getActivityId(),voList);
			}
			ActivityTaskVo atv = new ActivityTaskVo();
			atv.setActivityId(h.getActivityId());
			atv.setActivityName(h.getActivityName());
			atv.setAssignee(h.getAssignee());
			atv.setOpinion(h.getDeleteReason());
			atv.setEndTime(h.getEndTime());
			if(userMap.containsKey(h.getAssignee())){
				atv.setAssignee(userMap.get(h.getAssignee()));
			}
			voList.add(atv);
		}
		String key = "";
		Iterator<Map.Entry<String, List<ActivityTaskVo>>> iterator = result.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry<String, List<ActivityTaskVo>> next = iterator.next();
			String activityId = next.getValue().get(0).getActivityId();
			if(!key.equals(activityId)){
				boolean node = getCurrentNode(workflowExampleId, activityId);
				if(!node){
					iterator.remove();
				}
			}
			key = activityId;
		}
		return result;
		
	}

	/**
	 * 获取下一步待办的节点集合
	 * @param workflowExampleId
	 * @return
	 */
	private Map<String,ActivityTaskVo> getNextNodes(String workflowExampleId){
		Map<String,ActivityTaskVo> result = new HashMap<>();
		List<Task> list = taskService.createTaskQuery().processInstanceId(workflowExampleId).active().list();
		if(null!=list&&list.size()>0){
			System.out.println(list);
			for(Task t:list){
				if("StartEvent_0vzs06g".equals(t.getTaskDefinitionKey())){
					continue;
				}
				if(!result.containsKey(t.getTaskDefinitionKey())){
					ActivityTaskVo voList = new ActivityTaskVo();
					voList.setActivityId(t.getTaskDefinitionKey());
					voList.setActivityName(t.getName());
					result.put(t.getTaskDefinitionKey(),voList);
				}
			}
		}
		return result;
	}
	
	/**
	 * 校验当前节点是否完成
	 * @param workflowExampleId
	 * @param activityId
	 * @return
	 */
	private boolean getCurrentNode(String workflowExampleId,String activityId){
		boolean result = true;
		List<Task> list = taskService.createTaskQuery().processInstanceId(workflowExampleId).list();
		for(Task t:list){
			if(t.getTaskDefinitionKey().equals(activityId)){
				result = false;
			}
		}
		return result;
	}
	
	
	@Override
	public com.alibaba.fastjson.JSONArray getNextNodeHandlers(String workFlowId, String businessId, String businessType,Long projectId) {
		com.alibaba.fastjson.JSONArray currentNodeInformation = getCurrentNodeInformation(workFlowId,businessId,businessType,projectId);
		return currentNodeInformation;
	}
	
	
	
	/**
	 * 审批界面是否已过时（已审批过）
	 * @param workflowExampleId
	 * @param taskId
	 * @return
	 */
	private boolean approvalIsOutOfDate(String workflowExampleId,String taskId){
		boolean result = false;
		List<HistoricActivityInstance> hais = historyService.createHistoricActivityInstanceQuery().processInstanceId(workflowExampleId).finished().list();
		if(null == hais || hais.size() == 0){
			return result;
		}
		for(HistoricActivityInstance hai:hais){
			if(taskId.equals(hai.getTaskId())){
				result = true;
			}
		}
		return result;
	}
	
	
	/**
	 *
	 * @return
	 */
	@Override
	public String activityIds(String workflowExampleId) {
		List<Task> list = taskService.createTaskQuery().processInstanceId(workflowExampleId).list();
		List<HistoricActivityInstance> hais = historyService.createHistoricActivityInstanceQuery().processInstanceId(workflowExampleId).finished().list();
		if(null == hais || hais.size() == 0){
			return null;
		}
		String result = null;

		//查找最后一次节点任务
		/*for(int i = hais.size() -1 ;i>=0;i--){
			if("userTask".equals(hais.get(i).getActivityType())){
				result =  hais.get(i).getActivityId();
				break;
			}
		}*/
		Map<String,Object> map = new HashMap<>();
		for(HistoricActivityInstance hai:hais){
			if("userTask".equals(hai.getActivityType())){
				String userTask = (String)map.get("userTask");
				if(StringUtils.isBlank(userTask)){
					map.put("userTask",hai.getActivityId());
					map.put("milis",hai.getDurationInMillis());
				}else{
					Long milis = (Long)map.get("milis");
					if(hai.getDurationInMillis() > milis){
						map.put("userTask",hai.getActivityId());
						map.put("milis",hai.getDurationInMillis());
					}
				}
				result =  (String)map.get("userTask");
			}
		}
		
		//结束流无节点信息
		if(null != list && list.size() > 0){
		String taskKey = list.get(0).getTaskDefinitionKey();
		for(HistoricActivityInstance hai:hais){
			if(taskKey.equals(hai.getActivityId())){
				result = null;
			}
		}}
		//throw new InteractionFailedException("流程任务不存在");
		return result;
	}
	
	/**
	 * 获取节点任务名称
	 * @param workflowId
	 * @return
	 */
	@Override
	public String getCurrentNodeActivity(String workflowId) {
		LambdaQueryWrapper<BpmnTask> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(BpmnTask::getProcessId,workflowId)
					.orderByAsc(BpmnTask::getId);
		List<BpmnTask> taskList = iBpmnTaskService.list(wrapper);
		return taskList.get(0).getTaskKey();
	}
	
	/**
	 * 获取任务通知人
	 * @param taskKey
	 * @return
	 */
	@Override
	public List<String>  getNotifier(String taskKey){
		List<String> userNames = new ArrayList<>();
		LambdaQueryWrapper<BpmnTask> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(BpmnTask::getTaskKey,taskKey);
		BpmnTask task = iBpmnTaskService.getOne(wrapper);
		String sendNotifications = task.getSendNotifications();
		if(StringUtils.isNotBlank(sendNotifications)){
			String notifier = sendNotifications.replace("[", "").replace("]", "");
			if(StringUtils.isNotBlank(notifier)){
				String[] split = notifier.split(",");
				for (int i = 0 ;i < split.length;i++){
					userNames.add(split[i]);
				}
			}
		}
		//获取岗位通知人
		String sendPosts = task.getSendPost();
		getUserNamesByPost(sendPosts,userNames);
		return userNames.stream().distinct().collect(Collectors.toList());
	
	}
	
	/**
	 * 通知人为岗位
	 * @param sendPosts
	 * @return
	 */
	private void getUserNamesByPost(String sendPosts,List<String> userNames){
	    if(StringUtils.isBlank(sendPosts)){
	    	return ;
		}
		String notifier = sendPosts.replace("[", "").replace("]", "");
		if(StringUtils.isNotBlank(notifier)){
			String[] split = notifier.split(",");
			for (int i = 0 ;i < split.length;i++){
				List<String> users = getUserByPost(split[i]);
				userNames.addAll(users);
			}
		}
	}
	

	
	private List<String> getUserByPost(String postCode){
		postCode = postCode.replaceAll("\"", "");
		return notifierDao.getUsersByPost(postCode);
	}
	
	/**
	 * 去掉字符串组数包裹外壳
	 * @param candidatePost
	 */
	private List<String> removePackage(String candidatePost){
		List<String> posts = new ArrayList<>();
		if(StringUtils.isBlank(candidatePost)){
			return posts;
		}
		String postString = candidatePost.replace("[", "").replace("]", "");
		if(StringUtils.isNotBlank(postString)){
			String[] split = postString.split(",");
			for (int i = 0 ;i < split.length;i++){
				posts.add(split[i].replaceAll("\"",""));
			}
		}
		return posts;
	}
	
	/**
	 * 获取下一节点审批信息----用户停用专用
	 * @param workflowExampleId
	 * @return
	 */
	private com.alibaba.fastjson.JSONArray getCurrentNodeInformation2(String workflowExampleId){
		JSONArray nextArray = new com.alibaba.fastjson.JSONArray();
		List<Task> list = taskService.createTaskQuery().processInstanceId(workflowExampleId).list();
		if(null != list && list.size()>0){
			String taskDefinitionKey = list.get(0).getTaskDefinitionKey();
			boolean isClaim = isClaim(taskDefinitionKey);
			if(isClaim){
				boolean isNoPerson = false;
				List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(list.get(0).getId());
				String groupId = identityLinksForTask.get(0).getGroupId();
				for(IdentityLink identityLink:identityLinksForTask ){
					//按照岗位发起的流程
					if(null!=identityLink.getGroupId()){
						List<User> users = identityService.createUserQuery().memberOfGroup(identityLink.getGroupId()).list();
						if(null != users && users.size() > 0){
							for(User user:users){
								isNoPerson = true;
								setValue2(nextArray,user.getId(),identityLink.getTaskId(),taskDefinitionKey,isClaim);
							}
						}
					}else{
						setValue2(nextArray,identityLink.getUserId(),identityLink.getTaskId(),taskDefinitionKey,isClaim);
					}
					
				}
				//岗位下无人
				if(StringUtils.isNotBlank(groupId) && !isNoPerson){
					setValue2(nextArray,"空",identityLinksForTask.get(0).getTaskId(),taskDefinitionKey,isClaim);
					//throw new InteractionFailedException("流程按照岗位形式发起，岗位下无用户审批");
				}
			}else{
				for(Task t:list){
					List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(t.getId());
					for(IdentityLink identityLink:identityLinksForTask ){
						setValue2(nextArray,identityLink.getUserId(),identityLink.getTaskId(),taskDefinitionKey,isClaim);
					}
				}
			}
		}
		return nextArray;
	}
	
	private void  setValue2(com.alibaba.fastjson.JSONArray nextArray, String userId, String taskId,String taskKey,boolean isClaim){
		JSONObject nextObj = new JSONObject();
		nextObj.put("responsible_person", userId);
		nextObj.put("taskId", taskId);
		nextObj.put("taskKey", taskKey);
		nextObj.put("isClaim", isClaim);
		nextArray.add(nextObj);
	}

	/**
	 * 流程转办交接人
	 * @param schedules   代办事项
	 * @param handoverPerson  交接用户
	 */
	@Override
	public void setApproveHandover(List<Map<String,Object>> schedules,String userName,String handoverPerson) {
		if(schedules!=null&&schedules.size()>0){
			for(Map<String,Object> schedule:schedules){
				String taskId = String.valueOf(schedule.get("taskId"));
				String taskKey = String.valueOf(schedule.get("taskKey"));
				BpmnTask task = iBpmnTaskService.getOne(
						new LambdaQueryWrapper<BpmnTask>()
								.eq(BpmnTask::getTaskKey, taskKey)
				);
				Integer isClaim = task.getIsClaim();
				if(isClaim == 1){
					if(StringUtils.isNotBlank(task.getCandidateRelativePost())){
						taskService.deleteUserIdentityLink(taskId, userName,IdentityLinkType.ASSIGNEE);
					}
					taskService.deleteCandidateUser(taskId, userName);
					taskService.addCandidateUser(taskId, handoverPerson);
						
				}else{
				taskService.setAssignee(taskId,handoverPerson);
			}

			}
		}
		
	}

	/**
	 * 更新转办记录
	 * @param schedules
	 * @param userName
	 * @param handoverPerson
	 * @param userId
	 * @param transUserId
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void upTransferHistory(List<Map<String,Object>> schedules,String userName,String handoverPerson,Long userId,Long transUserId) {
		if(schedules!=null&&schedules.size()>0) {
			for (Map<String, Object> schedule : schedules) {
				String taskId = String.valueOf(schedule.get("taskId"));
				String processInstanceId = String.valueOf(schedule.get("processInstanceId"));
				LambdaQueryWrapper<BpmnTransferHistory> wrapper = new LambdaQueryWrapper<>();
				wrapper.eq(BpmnTransferHistory::getUserName, userName);
				wrapper.eq(BpmnTransferHistory::getTaskId,taskId);
				wrapper.eq(BpmnTransferHistory::getProcessInstanceId,processInstanceId);
				wrapper.eq(BpmnTransferHistory::getTransUserName,handoverPerson);
				long count=iBpmnTransferHistoryService.count(wrapper);
				if(count==0){
					BpmnTransferHistory history=new BpmnTransferHistory();
					history.setUserName(userName);
					history.setUserId(userId);
					history.setTaskId(taskId);
					history.setProcessInstanceId(processInstanceId);
					history.setTransUserName(handoverPerson);
					history.setTransUserId(transUserId);
					iBpmnTransferHistoryService.save(history);
				}
			}
		}
	}

	@Override
	public Map<String, String> getTransHistory(String userName) {
		Map<String, String> map=new HashMap<>();
		List<BpmnTransferHistory> list=iBpmnTransferHistoryService.list(
				new LambdaQueryWrapper<BpmnTransferHistory>().eq(BpmnTransferHistory::getUserName,userName)
		);
		if(null!=list&&list.size()>0){
			list.forEach(item->{
				map.put(item.getTaskId()+"-"+item.getProcessInstanceId(),item.getTransUserName());
			});
		}
		return map;
	}


}
